package cn.nn200433.db;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.db.dialect.Dialect;
import cn.hutool.db.dialect.DialectFactory;
import cn.hutool.db.dialect.DialectName;
import cn.nn200433.db.entity.DbParam;
import cn.smallbun.screw.core.Configuration;
import cn.smallbun.screw.core.engine.EngineConfig;
import cn.smallbun.screw.core.metadata.model.DataModel;
import cn.smallbun.screw.core.process.ProcessConfig;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

import javax.sql.DataSource;
import java.io.InputStream;
import java.util.Collections;
import java.util.List;

/**
 * 生成数据库文档
 *
 * @author song_jx
 * @date 2022-03-25 06:18:12
 */
public class DbToWord {

    /**
     * 转换
     *
     * @param dbParam    数据库参数
     * @param tplStream  模板数据流
     * @param exportPath 导出路径
     * @throws Exception 异常
     * @author song_jx
     */
    public void transform(DbParam dbParam, InputStream tplStream, String exportPath) throws Exception {
        // region 创建 数据源
        HikariConfig hikariConfig = new HikariConfig();
        hikariConfig.setJdbcUrl(dbParam.getJdbcUrl());
        hikariConfig.setUsername(dbParam.getUserName());
        hikariConfig.setPassword(dbParam.getPassword());
        hikariConfig.setMinimumIdle(2);
        hikariConfig.setMaximumPoolSize(5);

        String driverClassName = DialectFactory.identifyDriver(dbParam.getJdbcUrl());
        Dialect dialect = DialectFactory.newDialect(driverClassName);

        hikariConfig.setDriverClassName(driverClassName);

        // 设置可以获取tables remarks信息
        if (dialect.dialectName() == DialectName.MYSQL.name()) {
            hikariConfig.addDataSourceProperty("useInformationSchema", "true");
        }

        DataSource dataSource = new HikariDataSource(hikariConfig);

        // endregion

        List<String> ignoreTableNameList = CollUtil.defaultIfEmpty(StrUtil.split(dbParam.getIgnoreTableNames(), StrUtil.COMMA, Boolean.TRUE, Boolean.TRUE), Collections.emptyList());
        List<String> ignoreTablePrefixList = CollUtil.defaultIfEmpty(StrUtil.split(dbParam.getIgnoreTablePrefixs(), StrUtil.COMMA, Boolean.TRUE, Boolean.TRUE), Collections.emptyList());
        List<String> ignoreTableSuffixList = CollUtil.defaultIfEmpty(StrUtil.split(dbParam.getIgnoreTableSuffixs(), StrUtil.COMMA, Boolean.TRUE, Boolean.TRUE), Collections.emptyList());

        // region 生成配置
        Configuration dbConfig = Configuration.builder()
                //版本
                .version("1.0.0")
                //描述
                .description(dbParam.getDbDocumentName())
                //数据源
                .dataSource(dataSource)
                //生成配置
                .engineConfig(EngineConfig.builder().build())
                //生成配置
                .produceConfig(
                        ProcessConfig.builder()
                                //忽略表名
                                .ignoreTableName(ignoreTableNameList)
                                //忽略表前缀
                                .ignoreTablePrefix(ignoreTablePrefixList)
                                //忽略表后缀
                                .ignoreTableSuffix(ignoreTableSuffixList)
                                .build()
                )
                .build();
        // endregion

        //执行生成
        DataModel dataModel = new DataModelProcess(dbConfig).process();

        LoopRowTableRenderPolicy hackLoopTableRenderPolicy = new LoopRowTableRenderPolicy();
        Configure config = Configure.builder()
                .bind("tables", hackLoopTableRenderPolicy)
                .bind("columns", hackLoopTableRenderPolicy)
                .useSpringEL()
                .build();
        XWPFTemplate template = XWPFTemplate.compile(tplStream, config)
                .render(dataModel);
        template.writeToFile(exportPath);
    }

}
